import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * ABA 问题演示
 */
public class ABADemo1 {
    private static AtomicStampedReference<Integer> money =
            // 引入版本号
            new AtomicStampedReference<>(100, 0);

    public static void main(String[] args) throws InterruptedException {

        // 第 1 次点击转账按钮(-50)
        Thread t1 = new Thread(() -> {
            int old_money = money.getReference(); // 先得到余额
            int version = money.getStamp(); // 得到版本号
            // 执行花费 2s
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            money.compareAndSet(old_money, old_money - 50, version, version + 1);
        });
        t1.start();

        // 第 2 次点击转账按钮(-50)【不小心点击的，因为第一次点击之后没反应，所以不小心又点了一次】
        Thread t2 = new Thread(() -> {
            int old_money = money.getReference(); // 先得到余额
            int version = money.getStamp(); // 得到版本号
            money.compareAndSet(old_money, old_money - 50,
                    // 版本号+1
                    version, version + 1);
        });
        t2.start();

        // 给账户 +50 元
        Thread t3 = new Thread(() -> {
            // 执行花费 1s
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int old_money = money.getReference();
            int version = money.getStamp();
            money.compareAndSet(old_money, old_money + 50,
                    version, version + 1);
        });
        t3.start();

        t1.join();
        t2.join();
        t3.join();
        System.out.println("最终账号余额：" + money.getReference());
    }
}